define(function(require) {
    'use strict';

    var $ = require('jquery');

    var Button = function(element, options) {
        this.$element = $(element);
        this.options = $.extend({}, Button.DEFAULTS, options);
    };

    Button.DEFAULTS = {
        loadingText: '保存中...'
    };

    Button.prototype.setState = function(state) {
        var d = 'disabled';
        var $el = this.$element;
        var val = $el.is('input') ? 'val' : 'html';
        var data = $el.data();

        state = state + 'Text';

        if (!data.resetText) $el.data('resetText', $el[val]());

        $el[val](data[state] || this.options[state]);

        // push to event loop to allow forms to submit
        setTimeout(function() {
            state == 'loadingText' ?
                $el.addClass('ui-btn-' + d).attr(d, d) :
                $el.removeClass('ui-btn-' + d).removeAttr(d);
        }, 0);
    };

    Button.prototype.toggle = function() {
        var $parent = this.$element.closest('[data-toggle="buttons"]');
        var changed = true;

        if ($parent.length) {
            var $input = this.$element.find('input');
            if ($input.prop('type') === 'radio') {
                // see if clicking on current one
                if ($input.prop('checked') && this.$element.hasClass('active'))
                    changed = false;
                else
                    $parent.find('.active').removeClass('active');
            }
            if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change');
        }

        if (changed) this.$element.toggleClass('active');
    }


    // BUTTON PLUGIN DEFINITION
    // ========================

    var old = $.fn.btn;

    $.fn.btn = function(option) {
        return this.each(function() {
            var $this = $(this);
            var data = $this.data('kdt.btn');
            var options = typeof option == 'object' && option;

            if (!data) $this.data('kdt.btn', (data = new Button(this, options)));

            if (option == 'toggle') data.toggle();
            else if (option) data.setState(option);
        });
    };

    $.fn.btn.Constructor = Button;


    // BUTTON NO CONFLICT
    // ==================

    $.fn.btn.noConflict = function() {
        $.fn.btn = old;
        return this;
    };


    // BUTTON DATA-API
    // ===============

    $(document).on('click.kdt.btn.data-api', '[data-toggle^=button]', function(e) {
        var $btn = $(e.target);
        if (!$btn.hasClass('ui-btn')) $btn = $btn.closest('.ui-btn');
        $btn.button('toggle');
        e.preventDefault();
    });
});
